package com.leil.fileserver.client;

import com.leil.fileserver.exception.FileOptException;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.Result;
import io.minio.messages.DeleteError;
import java.io.InputStream;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class MinIOClient {

    private MinioClient minioClient;

    private PutObjectOptions options;


    public MinIOClient(String endpoint, String accessKey, String secretKey) throws FileOptException {
        try {
            this.minioClient = new MinioClient(endpoint, accessKey, secretKey);
        } catch (Exception e) {
            throw new FileOptException(e.getMessage());
        }
    }


    /**
     * 是否存在bucket
     * @param bucketName bucket名称
     * @return  是否存在
     */
    public boolean bucketExists(String bucketName) throws FileOptException {
        try {
            return this.minioClient.bucketExists(bucketName);
        } catch (Exception e) {
            throw new FileOptException(e.getMessage());
        }
    }


    /**
     * 创建bucket
     * @param bucketName    bucket名称
     */
    public void makeBucket(String bucketName) throws FileOptException {
        if (!this.bucketExists(bucketName)) {
            try {
                this.minioClient.makeBucket(bucketName);
            } catch (Exception e) {
                throw new FileOptException(e.getMessage());
            }
        }
    }

    /**
     * 上传对象
     * @param bucketName    Name of the bucket
     * @param objectName    文件名称
     * @param stream        文件流
     */
    public void putObject(String bucketName, String objectName, InputStream stream, long objectSize) throws FileOptException {
        try {
            PutObjectOptions options = new PutObjectOptions(objectSize, -1);
            this.minioClient.putObject(bucketName, objectName, stream, options);
        } catch (Exception e) {
            throw new FileOptException(e.getMessage());
        }
    }


    /**
     * 获取对象
     * @param bucketName    bucket名称
     * @param objectName    文件名称
     * @return              文件流
     */
    public InputStream getObject(String bucketName, String objectName) throws FileOptException {
        try {
            InputStream stream = this.minioClient.getObject(bucketName, objectName);
            return stream;
        } catch (Exception e) {
            throw new FileOptException(e.getMessage());
        }
    }

    /**
     * 获取对象的url
     * @param bucketName    bucket名称
     * @param objectName    文件名称
     * @return              URL
     * @throws FileOptException
     */
    public String getObjectUrl(String bucketName, String objectName) throws FileOptException {
        try {
            return this.minioClient.getObjectUrl(bucketName, objectName);
        } catch (Exception e) {
            throw new FileOptException(e.getMessage());
        }
    }


    /**
     * 移除一个文件
     * @param bucketName    bucket名称
     * @param objectName    文件名称
     */
    public void removeObject(String bucketName, String objectName) throws FileOptException {
        try {
            this.minioClient.removeObject(bucketName, objectName);
        } catch (Exception e) {
            throw new FileOptException(e.getMessage());
        }
    }


    /**
     * 移除bucket中的一组对象
     * @param bucketName        bucket名称
     * @param objectNames       文件名称列表
     * @throws FileOptException
     */
    public void removeObjects(String bucketName, Iterable<String> objectNames) throws FileOptException {
        Iterable<Result<DeleteError>> results = this.minioClient.removeObjects(bucketName, objectNames);
        String errors = StreamSupport.stream(results.spliterator(), false)
                .map(result -> {
                    String errorMessage = "";
                    try {
                        errorMessage = result.get().objectName() + ":" + result.get().message();
                    } catch (Exception e) {
                        errorMessage = e.getMessage();
                    }
                    return errorMessage;
                }).collect(Collectors.joining(","));
        throw new FileOptException(errors);
    }

}
